『
JavaFX 画像エフェクト』の記事で書ききれなかったBlendエフェクトについてみていく。Blendエフェクトでは、2つのオブジェクトが重なり合う際の色の混ぜ方を指定できる。個人的には今までありそうでなかった加算合成(ゲームのエフェクトでよく使われる)が用意されていることがとても嬉しい。
■ ブレンド・モード一覧
Blendエフェクトで設定可能なブレンドモードの一覧を以下に示す。各ブレンドのイメージはサンプルコードで見ていく。なお、代表的な合成方法であるαブレンドに相当するBlendエフェクトはないが、Node.setOpacity関数で透明度を指定することでαブレンドと同等の効果を得ることができる。
分類 |
ブレンド・モード |
内容 |
一般 |
SRC_OVER |
上書きモード。ブレンド・モードを指定しない場合に指定される |
SRC_ATOP |
Porter-Duff source atop destinationルールで合成する |
明るい系 |
ADD |
加算合成。各RGB値を加算する |
SCREEN |
スクリーン。各RGB値を反転して掛け合わし、結果をさらに反転する |
OVERLAY |
オーバーレイ。入力の各RGB値が下入力の色に応じて乗算またはスクリーン処理される |
HARD_LIGHT |
ハードライト。入力の各RGB値が最上部の入力の色に応じて乗算またはスクリーン処理される |
SOFT_LIGHT |
ソフトライト。入力の各RGB値が最上部の入力の色に応じて暗くなるか明るくなる |
LIGHTEN |
各RGB値の明るい方が選択される |
COLOR_DODGE |
下入力の各RGB値が最上部の入力の色成分の補数で除算されて結果の色が生成される |
暗い系 |
COLOR_BURN |
焼き入れ。下入力の各RGB値の補数が最上部の入力の色成分で除算され、そのすべてが反転されて結果の色が生成される |
MULTIPLY |
乗算合成。各RGB値を乗算する |
DARKEN |
2つの入力の色成分の暗い方が選択されて結果の色が生成されます。 |
EXCLUSION |
排他的論理輪。2つの入力の色成分が乗算され、2倍にされてから、下入力の色成分の合計から減算されて結果の色が生成されます。 |
DIFFERENCE |
2つの入力の色成分の暗い方が明るい方から減算されて結果の色が生成されます。 |
色置換 |
RED |
赤色成分の置換 |
GREEN |
緑成分の置換 |
BLUE |
青成分の置換 |
■ サンプルコード
各ブレンドモードの動作について確認するサンプルを以下に示す。サンプルでは各行ごとにブレンド・モードの出力イメージを出力しており、『ブレンド名称』『シェイプ(赤の長方形)の合成』『画像の合成』の3つを出力している。
◇サンプルコード
package application_fx;
import java.io.File;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.effect.Blend;
import javafx.scene.effect.BlendMode;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class TestBlendMode extends Application {
public static void main(String[] args)
{
launch( args );
}
@Override
public void start(Stage primaryStage) throws Exception
{
// シーングラフの構成
VBox root = new VBox( 1.0f );
// 画像読み込み
Image img = new Image( new File( "img/chara_one.png" ).toURI().toString() );
// 各ブレンドモードのサンプルを追加
root.getChildren().add( createBlendSample( img , BlendMode.SRC_OVER ) ); // 上書き
root.getChildren().add( createBlendSample( img , BlendMode.SRC_ATOP ) ); // ATOP
root.getChildren().add( createBlendSample( img , BlendMode.ADD ) ); // 加算合成
root.getChildren().add( createBlendSample( img , BlendMode.SCREEN ) ); // スクリーン
root.getChildren().add( createBlendSample( img , BlendMode.OVERLAY ) ); // オーバーレイ
root.getChildren().add( createBlendSample( img , BlendMode.HARD_LIGHT ) ); // ハードライト
root.getChildren().add( createBlendSample( img , BlendMode.SOFT_LIGHT ) ); // ソフトライト
root.getChildren().add( createBlendSample( img , BlendMode.LIGHTEN ) ); // 明るい色を選択
root.getChildren().add( createBlendSample( img , BlendMode.COLOR_DODGE ) ); // 補数で除算
root.getChildren().add( createBlendSample( img , BlendMode.COLOR_BURN ) ); // 焼き入れ
root.getChildren().add( createBlendSample( img , BlendMode.MULTIPLY ) ); // 乗算
root.getChildren().add( createBlendSample( img , BlendMode.DARKEN ) ); // 暗い色を選択
root.getChildren().add( createBlendSample( img , BlendMode.EXCLUSION ) ); // 排他的論理輪
root.getChildren().add( createBlendSample( img , BlendMode.DIFFERENCE ) ); // 減産
root.getChildren().add( createBlendSample( img , BlendMode.RED ) ); // 赤成分置換
root.getChildren().add( createBlendSample( img , BlendMode.BLUE ) ); // 青成分置換
root.getChildren().add( createBlendSample( img , BlendMode.GREEN ) ); // 緑成分置換
// シーンの作成
Scene scene = new Scene( root , 300 , 800 , Color.web( "9FCC7F" ) );
// ウィンドウ表示
primaryStage.setScene( scene );
primaryStage.show();
}
/**
* ブレンド・モードを指定して、サンプル画像を出力
* @param img
* @return
*/
public Node createBlendSample( Image img , BlendMode mode )
{
// 水平レイアウトを作成
Group root = new Group();
// 表示オブジェクトを作成
Text explainText = new Text( mode.toString() );
Rectangle rect = new Rectangle( 48 , 32 , Color.BROWN );
ImageView imgView = new ImageView( img );
// プロパティ設定
rect.setOpacity( 0.5 );
// 位置あわせ
rect.setLayoutX( 100 );
imgView.setLayoutX( 132 );
// ブレンドモードを指定せずノードを追加
root.getChildren().addAll( explainText , rect , imgView );
root.setEffect( new Blend( mode ) );
// 戻り値を返す
return root;
}
}
◇リソース
(chara_one.png)
◇実行結果
◇解説
このプログラムのメインは86行目でブレンド・モードを指定し、Blendエフェクトを設定している箇所である。
■ 参照
- JavaDoc - クラスBlend
- JavaDoc - 列挙型BlendMode